<template>
	<div>
    <div class="department">
      <el-input style="margin:0 0 20px 10px;width: 270px;" placeholder="输入关键字进行过滤" v-model="filterText">
      </el-input>
      <el-tree class="filter-tree" :data="listDatas"
      :props="defaultProps" default-expand-all
        :filter-node-method="filterNode" ref="tree" >
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <span
            :style="data.level === 1 ? 'font-weight: bold;font-size: 16px;' : ''">{{ node.label }}</span>
          <el-dropdown trigger="hover" @command="handleCommand">
            <div class="el-dropdown-link"><img src="../../../assets/img/dian.png" /></div>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item :command="{type: 1, obj: data}" :disabled="data.upDisabled">上移
              </el-dropdown-item>
              <el-dropdown-item :command="{type: 2, obj: data}" :disabled="data.downDisabled">下移
              </el-dropdown-item>
              <el-dropdown-item :command="{type: 3, obj: data}">编辑</el-dropdown-item>
              <el-dropdown-item :command="{type: 4, obj: data}">添加子部门</el-dropdown-item>
              <el-dropdown-item :command="{type: 5, obj: data}" :disabled="data.level===1">删除</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </span>
      </el-tree>
      <div class="btn">
        <el-button @click="openDepartment(1)" size="small" type="primary">新建部门</el-button>
      </div>
    </div>
    <!-- 新建/编辑部门 -->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="departmentVisible" :close-on-click-modal="false" width="500px">
      <el-form ref="departmentForm" :rules="departmentRules" :model="departmentTemp" label-position="top" style="width: 400px;">
        <div>
          <el-form-item label="部门名称" prop="label">
            <el-input v-model="departmentTemp.label" />
          </el-form-item>
          <el-form-item v-if="departmentTemp.id == null || departmentTemp.id != 0" label="上级部门" prop="department">
            <el-cascader
              style="width: 100%;"
              value="id" 
              :show-all-levels="false"
              v-model="departmentTemp.department"
              :options="listDatas"
              :props="selectProps"
              @change="handleChange"
              clearable></el-cascader>
          </el-form-item>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="departmentVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="saveDepartment()">
          确认
        </el-button>
      </div>
    </el-dialog>
	</div>
</template>

<script>
	import { departmentTree, departmentDelete, departmentSave, departmentSort } from '@/api/usrs/index'
	export default {
		name: 'department',
		watch: {
			filterText(val) {
				this.$refs.tree.filter(val);
			},
		},
    computed: {

    },
		data() {
			return {
				elLoading: false,
				textMap: {
					addDepartment: '新增部门',
					editDepartment: '编辑部门',
				},
				dialogStatus: '',
				departmentVisible: false, //部门弹窗状态
				departmentRules: {
					label: [
						{ required: true, message: '部门名称不能为空', trigger: 'blur'},
						{ min:1, max: 20, message: '长度在20字以内', trigger: 'blur' }
					],
					department: [{ required: true, message: '请选择上级部门', trigger: 'blur' }]
				},
				departmentTemp: {
					id: undefined,
					label: '',
					department: []
				},
				filterText: '',
				data: [
					// {
					// 	id: 1,
					// 	label: 'XXX监管局',
					// 	level: 1,
					// 	deleted: false,
					// 	children: [
					// 		{
					// 			id: 2,
					// 			label: '业务一部',
					// 			deleted: true,
					// 			children: [{
					// 				id: 5,
					// 				deleted: true,
					// 				label: '业务一组'
					// 			}, {
					// 				id: 6,
					// 				deleted: true,
					// 				label: '业务二组'
					// 			}]
					// 		},
					// 		{
					// 			id: 4,
					// 			label: '业务二部',
					// 			deleted: false,
					// 			children: [{
					// 				id: 9,
					// 				deleted: false,
					// 				label: '业务二部一组'
					// 			}, {
					// 				id: 10,
					// 				deleted: true,
					// 				label: '业务二部二组'
					// 			}]
					// 		}, {
					// 			id: 3,
					// 			label: '业务三部',
					// 			deleted: false,
					// 			children: []
					// 		}
					// 	]
					// }
				],
				defaultProps: {
					children: 'children',
					label: 'label'
				},
				selectProps: {
					value: 'id',
					checkStrictly: true
				},
				listDatas: []
			};
		},
		mounted() {
			this.getTreeList();
		},
		methods: {
			//获取部门树
			getTreeList() {
				this.openLoading()
				departmentTree().then(res => {
					this.listDatas = this.initData([res.data])
					this.$emit("refreshDepartment", this.listDatas);
					this.closeLoading()
				}).catch(error => {
					this.closeLoading()
					console.log(error)
				})
			},
			handleChange() {
				// console.log(this.departmentTemp)
			},
			//打开部门二级弹窗 type 1创建部门  2编辑部门 3新增子部门
			openDepartment(type, row) {
      	let result = []
				if(type === 1) {
					this.departmentTemp = {
						id: undefined,
						label: '',
						department: null
					}
				} else if( type === 2){ //编辑部门
					this.departmentTemp = row
					this.getParentIds(this.listDatas, row, result)
					let ids = result.map(item => item.id)
					this.departmentTemp.department = ids.slice(0, ids.length - 1)
				} else {
					this.getParentIds(this.listDatas, row, result)
					let ids = result.map(item => item.id)
          this.departmentTemp = {
						id: undefined,
						label: '',
						department: ids
					}
				}
				
				this.dialogStatus = type === 1 || type === 3 ? 'addDepartment' : 'editDepartment';
				this.departmentVisible = true;
				this.$nextTick(() => {
					this.$refs['departmentForm'].clearValidate()
				})
			},
			//保存部门
			saveDepartment() {
				this.$refs['departmentForm'].validate((valid) => {
					if (valid) {
						let obj = {}
						if(this.departmentTemp.parentId && this.departmentTemp.parentId < 0) {
							obj = {
								id: 0,
								name: this.departmentTemp.label,
								parentId: -1,
								sortNum: 0
							}
						} else {
							let pId = this.departmentTemp.department[this.departmentTemp.department.length - 1]
							let result = []
							this.getParentIds(this.listDatas, {id: pId}, result)
							let parent = result[result.length - 1]
							//修改时不能把上级部门换到自己下面以及其子部门下面
							if(this.dialogStatus === 'editDepartment') {
								if(this.departmentTemp.id === pId) {
									this.$message({
										type: 'warning',
										message: '不能选择当前部门作为上级部门!'
									})
									return
								}
								if(this.departmentTemp.children && this.departmentTemp.children.length > 0) {
									let childIds = []
									this.getChildIds(this.departmentTemp.children,childIds)
									if(childIds.indexOf(pId) != -1) {
										this.$message({
											type: 'warning',
											message: '不能选择当前部门下子部门作为上级部门!'
										})
										return
									}
								}
								
								
							}
							let sortNum = 1
							if(parent.children && parent.children.length > 0) {
								sortNum = parent.children[parent.children.length-1].sortNum + 1
							}
							obj = {
								name: this.departmentTemp.label,
								parentId: pId,
								sortNum: sortNum
							}
							if(this.departmentTemp.id) {
								obj.id = this.departmentTemp.id
								obj.sortNum = this.departmentTemp.sortNum
							}
						}
						departmentSave(obj).then(() => {
							this.departmentVisible = false
							this.getTreeList();
							if(this.dialogStatus === 'editDepartment') {
								this.$emit("selectDepartment", null);
							}
						})
					}
				})
			},
			//修改部门排序
			

			//删除部门
			deleteDepartment(res) {
        if(res.deleted) {
          this.$confirm('', '确认删除该部门?', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
						departmentDelete({id: res.id}).then(() => {
							this.$message({
								type: 'success',
								message: '删除成功!'
							});
							this.getTreeList();
						})
          }).catch(() => {
            // this.$message({
            //   type: 'info',
            //   message: '已取消删除'
            // });          
          });
        } else {
          this.$alert('请先移除部门内所有人员再进行操作', '确认删除该部门?', {
            confirmButtonText: '确定',
            callback: action => {
              this.$message({
                type: 'info',
                message: `action: ${ action }`
              });
            }
          });
        }
			},
			
			//初始化部门
			initData(datas, parentId) {
				let res = []
				datas.forEach((item, index) => {
					let tmp = {
						...item
					}
					tmp.deleted = true
					if(tmp.id < 1) {
						tmp.level = 1
						tmp.deleted = false
					}
					tmp.label = tmp.name
					tmp.upDisabled = false
					tmp.downDisabled = false
					if (parentId) tmp.parentId = parentId
					if (index < 1) tmp.upDisabled = true
					if (index + 1 >= datas.length) tmp.downDisabled = true
					if (tmp.children) {
						tmp.children = this.initData(tmp.children, tmp.id)
					}
					res.push(tmp)
				})
				return res
			},
			handleCommand(data) {
				if (this.filterText) {
					this.$message({
						type: 'warning',
						message: '搜索状态下暂时无法操作'
					})
					return
				}
				switch (data.type) {
					case 1: //上移
						this.findList(data)
						break;
					case 2: //下移
						this.findList(data)
						break;
					case 3: //编辑
						this.openDepartment(2, data.obj)
						break;
					case 4: //新增子部门
						this.openDepartment(3, data.obj)
						break;
					case 5: //删除部门
						this.deleteDepartment(data.obj)
						break;
				}
			},

			//部门移动操作
			findList(data) {
				let pId = data.obj.parentId
				let result = []
				this.getParentIds(this.listDatas, {id: pId}, result)
				let parent = result[result.length - 1]
				if(parent.children && parent.children.length > 0) {
					let index = 0
					parent.children.forEach((item, ind) => {
						if(item.id === data.obj.id) index = ind
					})
					let changeObj = data.type === 1 ? parent.children[index - 1] : parent.children[index + 1]
					this.changeIndex([{id: changeObj.id, sortNum: data.obj.sortNum},{id: data.obj.id, sortNum: changeObj.sortNum}])
					
				}
			},

			changeIndex(params) {
				departmentSort(params).then(() => {
					this.getTreeList();
				}).catch(()=>{

				})
			},

			//获取上级部门ids
			getParentIds(data, target, result) {
				for (let i in data) {
					let item = data[i]
					if (item.id === target.id) {
						//将查找到的目标数据加入结果数组中
						//可根据需求unshift(item.id)或unshift(item)
						result.unshift(item)
						return true
					}
					if (item.children && item.children.length > 0) {
						let ok = this.getParentIds(item.children, target, result)
						if (ok) {
							result.unshift(item)
							return true
						}
					}
				}
				//走到这说明没找到目标
				return false
			},
			//获取所有子部门ids
			getChildIds(data, result) {
				for (let i in data) {
					let item = data[i]
					//将查找到的目标数据加入结果数组中
					//可根据需求unshift(item.id)或unshift(item)
					result.unshift(item.id)
					if (item.children && item.children.length > 0) {
						let ok = this.getChildIds(item.children, result)
						if (ok) {
							result.unshift(item.id)
							return true
						}
					}
				}
				//走到这说明没找到目标
				return false
			},
			filterNode(value, data) {
				if (!value) return true;
				return data.label.indexOf(value) !== -1;
			},
			openLoading(){
        this.elLoading = this.$loading({
          lock: true,
          text: '加载中',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });
      },
      closeLoading(){
        this.elLoading.close();
      },
		},
	}
</script>

<style lang="scss" scoped>
	.custom-tree-node {
		flex: 1;
		display: flex;
		align-items: center;
		justify-content: space-between;
		font-size: 14px;
		padding-right: 8px;
	}

	.body {
		height: 100%;
		border: 1px solid rgb(230, 230, 230);
		display: flex;
	}

	.department {
		width: 300px;
		margin: 10px 0;
		padding-right: 10px;
	}

	.user {
		width: calc(100% - 300px);
		padding: 10px;
		border-left: 1px solid rgb(230, 230, 230);
		.btns {
			width: 360px;
			display: flex;
			float: right;
			justify-content: space-around;
		}
	}

	.btn {
		margin: 20px 10px 0 10px;
		text-align: right;
    display: flex;
    justify-content: space-between;
	}
</style>
